package com.yizisu.playerlibrary.activity

import android.os.Bundle
import android.os.Environment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.RecyclerView
import com.google.android.exoplayer2.offline.Download
import com.google.android.exoplayer2.offline.DownloadManager
import com.yizisu.playerlibrary.R
import com.yizisu.playerlibrary.databinding.PlayerLibRcvCacheItemBinding
import com.yizisu.playerlibrary.service.download.PlayerDownload
import com.yizisu.playerlibrary.service.download.PlayerTransformer
import java.lang.Exception
import java.math.BigDecimal
import java.math.RoundingMode

/**
 * 缓存视频的Fragment
 */
class PlayerLibraryCacheFragment : Fragment(), PlayerDownload.NotificationListener {
    companion object {
        fun newInstance(ids: Array<String>) = PlayerLibraryCacheFragment().apply {
            arguments = createArguments(ids)
        }

        fun createArguments(ids: Array<String>) = Bundle().apply {
            putStringArray("datas", ids)
        }
    }

    private val ids by lazy {
        arguments?.getStringArray("datas")
    }

    private val allDownloads by lazy {
        PlayerDownload.getAllDownloads().let {
            if (ids.isNullOrEmpty()) {
                it
            } else {
                it.filter {
                    var hasDownload = false
                    ids?.forEach { id ->
                        if (id == it.request.id) {
                            hasDownload = true
                            return@forEach
                        }
                    }
                    hasDownload
                }.toMutableList()
            }
        }
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_player_library_cache, container, false)
    }

    private val rcvAdapter = RcvAdapter()
    val recyclerView by lazy {
        requireView().findViewById<RecyclerView>(R.id.rcvCache)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        recyclerView.adapter = rcvAdapter
        PlayerDownload.addNotificationListener(this)
    }

    override fun onDestroyView() {
        PlayerDownload.removeNotificationListener(this)
        super.onDestroyView()
    }

    private inner class RcvAdapter :
        RecyclerView.Adapter<RcvHolder>() {
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RcvHolder {
            return RcvHolder(
                PlayerLibRcvCacheItemBinding.inflate(
                    LayoutInflater.from(parent.context),
                    parent,
                    false
                )
            ).apply {
                binding.tvDelete.setOnClickListener {
                    val data = allDownloads[adapterPosition]
                    PlayerDownload.removeDownload(data.request.id)
                    allDownloads.remove(data)
                    notifyItemRemoved(adapterPosition)
                }
                binding.root.setOnClickListener {
                    val data = allDownloads[adapterPosition]
                    FullScreenVideoActivity.start(
                        requireActivity() as AppCompatActivity,
                        data.request.uri.toString()
                    )
                }
                //文件转换示例
//                binding.root.setOnLongClickListener {
//                    val data = allDownloads[adapterPosition]
//                    data.request.customCacheKey
//                    PlayerTransformer(
//                        data.request.toMediaItem(),
//                        it.context.getExternalFilesDir(Environment.DIRECTORY_MOVIES)!!.path + "/ceshi.mp4",
//                        true
//                    ).start()
//                    true
//                }
                binding.tvStatus.setOnClickListener {
                    allDownloads[adapterPosition].request.id.let {
                        PlayerDownload.getDownload(it)?.let { data ->
                            when (data.state) {
                                Download.STATE_COMPLETED -> {

                                }
                                Download.STATE_DOWNLOADING -> {
                                    PlayerDownload.stopDownload(data.request.id, 1)
                                }
                                Download.STATE_FAILED,
                                Download.STATE_QUEUED,
                                Download.STATE_STOPPED -> {
                                    PlayerDownload.resumeDownload(data.request.id)
                                }
                                Download.STATE_REMOVING -> {

                                }
                                Download.STATE_RESTARTING -> {

                                }
                            }
                        }
                    }
                }
            }
        }

        override fun getItemCount(): Int {
            return allDownloads.count()
        }

        override fun onBindViewHolder(holder: RcvHolder, position: Int) {
            bindViewHolder(holder, position, true)
        }

        fun bindViewHolder(holder: RcvHolder, position: Int, isBind: Boolean) {
            val binding = holder.binding
            val data = allDownloads[position]
            if (isBind) {
                binding.tvName.text = data.request.id
            }
            binding.tvDes.text = getFormatSize(data.bytesDownloaded.toFloat())
            binding.tvProgress.progress =
                (binding.tvProgress.max * (data.percentDownloaded / 100f)).toInt()
            val state = when (data.state) {
                Download.STATE_COMPLETED -> {
                    "已完成"
                }
                Download.STATE_DOWNLOADING -> {
                    "下载中"
                }
                Download.STATE_FAILED -> {
                    "已失败"
                }
                Download.STATE_QUEUED -> {
                    "等待中"
                }
                Download.STATE_REMOVING -> {
                    "删除中"
                }
                Download.STATE_RESTARTING -> {
                    "重试中"
                }
                Download.STATE_STOPPED -> {
                    "已暂停"
                }
                else -> {
                    ""
                }
            }
            if (binding.tvStatus.text.toString() != state) {
                binding.tvStatus.text = state
            }
            PlayerDownload.onCacheVideoBindHolderListener?.invoke(binding, data, isBind)
        }
    }

    private class RcvHolder(val binding: PlayerLibRcvCacheItemBinding) :
        RecyclerView.ViewHolder(binding.root)

    override fun updateNotification(downloads: MutableList<Download>) {
        downloads.forEach {
            checkDownload(it)
        }
    }

    private fun checkDownload(it: Download) {
        allDownloads.forEachIndexed { index, download ->
            if (it.request.id == download.request.id) {
                allDownloads[index] = it
                val holder = recyclerView.findViewHolderForLayoutPosition(index)
                if (holder is RcvHolder) {
                    rcvAdapter.bindViewHolder(holder, index, false)
                }
                return@forEachIndexed
            }
        }
    }

    override fun onDownloadChanged(
        downloadManager: DownloadManager,
        download: Download,
        finalException: Exception?
    ) {
        super.onDownloadChanged(downloadManager, download, finalException)
        checkDownload(download)
    }

    override fun onDownloadRemoved(downloadManager: DownloadManager, download: Download) {
        super.onDownloadRemoved(downloadManager, download)
        allDownloads.toMutableList().forEachIndexed { index, download ->
            if (download.request.id == download.request.id) {
                allDownloads.removeAt(index)
                rcvAdapter.notifyItemRemoved(index)
            }
        }
    }

    private fun getFormatSize(size: Float): String {
        return when {
            size < 1024 -> {//不足1k
                "${size}B"
            }
            size < 1024 * 1024 -> {//不足1m
                "${(size / 1024).keepTwoPoint()}KB"
            }
            size < 1024 * 1024 * 1024 -> {//不足1g
                "${(size / 1024 / 1024).keepTwoPoint()}M"
            }
            else -> {
                "${(size / 1024 / 1024 / 1024).keepTwoPoint()}G"
            }
        }
    }

    private fun Float?.keepTwoPoint(roundingMode: RoundingMode = RoundingMode.HALF_EVEN): String {
        val value = this?.toString()
        return try {
            if (value == null) {
                "0.00"
            } else {
                BigDecimal(value).setScale(2, roundingMode)?.toString() ?: value
            }
        } catch (e: Throwable) {
            "0.00"
        }
    }
}